package com.mrd.gtimpframe.service;

import com.github.pagehelper.PageInfo;
import com.mrd.SMSUtil;
import com.mrd.exception.QueryException;
import com.mrd.gtimp.base.entity.User;
import com.mrd.gtimp.business.entity.Commodity;
import com.mrd.gtimp.business.entity.Declaration;
import com.mrd.gtimp.business.entity.InspectionGoods;
import com.mrd.gtimp.business.entity.InspectionGoodsDetails;
import com.mrd.gtimp.business.service.DeclarationBiz;
import com.mrd.gtimpframe.action.VerifyAction;
import com.mrd.gtimpframe.entity.DeclaCheckContent;
import com.mrd.gtimpframe.entity.DeclaCheckCtDeptRef;
import com.mrd.gtimpframe.entity.DeclaCheckCtItemRef;
import com.mrd.gtimpframe.entity.DeclaCheckGoodsRef;
import com.mrd.gtimpframe.entity.DeclaCheckResult;
import com.mrd.gtimpframe.entity.DeclaCheckTracking;
import com.mrd.gtimpframe.entity.Dictionary;
import com.mrd.gtimpframe.entity.ResultNopassRef;
import com.mrd.gtimpframe.entity.UserService;
import com.mrd.gtimpframe.repository.DeclaCheckContentMapper;
import com.mrd.gtimpframe.repository.DeclaCheckCtDeptRefMapper;
import com.mrd.gtimpframe.repository.DeclaCheckCtItemRefMapper;
import com.mrd.gtimpframe.repository.DeclaCheckGoodsRefMapper;
import com.mrd.gtimpframe.repository.DeclaCheckResultMapper;
import com.mrd.gtimpframe.repository.DeclaCheckTrackingMapper;
import com.mrd.gtimpframe.repository.ResultNopassRefMapper;
import com.mrd.gtimpframe.repository.UserServiceMapper;
import com.mrd.util.LoginUtil;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

/**
 * Created by dark on 17/7/24.
 */
@Service
public class VerifyBiz {

    @Resource
    private DeclaCheckCtItemRefMapper declaCheckCtItemRefMapper;
    @Resource
    private DeclaCheckCtDeptRefMapper declaCheckCtDeptRefMapper;
    @Resource
    private DeclaCheckGoodsRefMapper declaCheckGoodsRefMapper;
    @Resource
    private DeclaCheckContentMapper declaCheckContentMapper;
    @Resource
    private DeclaCheckTrackingMapper declaCheckTrackingMapper;
    @Resource
    private DeclarationBiz declarationBiz;
    @Resource
    private UserServiceMapper userServiceMapper;
    @Resource
    private DeclaCheckResultMapper declaCheckResultMapper;
    @Resource
    private ResultNopassRefMapper resultNopassRefMapper;
    @Resource
    private DictionaryService dictionaryService;
    @Resource
    private VerifyBiz verifyBiz;
    @Value("${sms.userId}")
    private String userId;
    @Value("${sms.password}")
    private String password;
    private final org.slf4j.Logger log = LoggerFactory.getLogger(VerifyBiz.class);

    @Transactional
    public void transformOldData(List<InspectionGoods> inspectionGoodsList) {
        if (CollectionUtils.isNotEmpty(inspectionGoodsList)) {
            for (InspectionGoods inspectionGoods : inspectionGoodsList) {
                if (inspectionGoods == null) {
                    break;
                }
                Declaration declaration = inspectionGoods.getDeclaration();
                if (declaration != null) {
                    DeclaCheckTracking tracking = new DeclaCheckTracking();
                    tracking.setId(com.mrd.util.StringUtils.getUUID());
                    tracking.setDid(inspectionGoods.getDeclaration().getId());
                    tracking.setCreateTime(inspectionGoods.getCreateTime());
                    String verifyState = inspectionGoods.getState();

                    String state = declaration.getState();
                    if (StringUtils.isNotEmpty(state) && state.equals("DS05")) {//已完成
                        verifyState = "4";
                    } else {
                        if (StringUtils.isNotEmpty(verifyState) && "2".equalsIgnoreCase(verifyState)) {
                            //已查验
                            verifyState = "1";
                        } else {
                            verifyState = "0";
                        }
                    }
                    tracking.setBizStatus(verifyState);
                    declaCheckTrackingMapper.insertSelective(tracking);

                    List<InspectionGoodsDetails> detailsList = inspectionGoods.getInspectionGoodsDetailsList();
                    String creator = "";
                    if (CollectionUtils.isNotEmpty(detailsList)) {
                        for (InspectionGoodsDetails inspectionGoodsDetails : detailsList) {
                            creator = inspectionGoodsDetails.getCreator().getAccount();
                            String inspectionCompany = inspectionGoodsDetails.getInspectionCompany();
                            String extCompany = inspectionGoodsDetails.getInspectionExt();
                            String inspectionProject = inspectionGoodsDetails.getInspectionProject();
                            String inspectionSituation = inspectionGoodsDetails.getInspectionSituation();

                            DeclaCheckContent content = new DeclaCheckContent();
                            content.setId(com.mrd.util.StringUtils.getUUID());
                            content.setContainerNo(inspectionGoods.getContainerNo());
                            content.setTrackingId(tracking.getId());
                            content.setCreator(inspectionGoodsDetails.getCreator().getAccount());
                            content.setCreateTime(inspectionGoodsDetails.getCreateTime());
                            if (StringUtils.isNotEmpty(inspectionCompany)) {
                                content.setOtherInspectDept(inspectionCompany.equals("其他") ? extCompany : inspectionCompany);
                            }
                            if (StringUtils.isNotEmpty(inspectionProject)) {
                                content.setOtherInspectProject(inspectionProject);
                            }
                            declaCheckContentMapper.insertSelective(content);


                            DeclaCheckResult checkResult = new DeclaCheckResult();
                            checkResult.setId(com.mrd.util.StringUtils.getUUID());
                            checkResult.setContentId(content.getId());
                            checkResult.setCreator(content.getCreator());
                            checkResult.setCreateTime(content.getCreateTime());
                            checkResult.setDescription(inspectionSituation);
                            checkResult.setBizStatus(tracking.getBizStatus());
                            declaCheckResultMapper.insertSelective(checkResult);

                            Commodity commodity = inspectionGoods.getInspectionCommodity();
                            if (commodity != null) {
                                DeclaCheckGoodsRef goodsRef = new DeclaCheckGoodsRef();
                                goodsRef.setContentId(content.getId());
                                goodsRef.setGoodsId(commodity.getId());
                                goodsRef.setCreateTime(content.getCreateTime());
                                goodsRef.setCreator(content.getCreator());
                                declaCheckGoodsRefMapper.insertSelective(goodsRef);
                            }


                            DeclaCheckCtDeptRef deptRef = new DeclaCheckCtDeptRef();
                            deptRef.setContentId(content.getId());
                            deptRef.setItemId("47854ce9672a47a29e2c9f1687866955");//todo 其他查验单位ID
                            deptRef.setCreateTime(content.getCreateTime());
                            deptRef.setCreator(content.getCreator());
                            declaCheckCtDeptRefMapper.insertSelective(deptRef);


                            DeclaCheckCtItemRef itemRef = new DeclaCheckCtItemRef();
                            itemRef.setContentId(content.getId());
                            itemRef.setItemId("5e980729ce83470da47a35baaf47d3dd");//todo 其他查验项目ID
                            itemRef.setCreateTime(content.getCreateTime());
                            itemRef.setCreator(content.getCreator());
                            declaCheckCtItemRefMapper.insertSelective(itemRef);


                        }
                    }
                    tracking.setCreator(creator);
                    declaCheckTrackingMapper.updateByPrimaryKeySelective(tracking);
                }
            }
        }
    }

    @Transactional
    public DeclaCheckTracking saveCheckRecord(VerifyAction.CheckRecord checkRecord, User user) {
        try {
            if (checkRecord != null) {
                String bussId = checkRecord.getBussId();
                String cTime = checkRecord.getCtime();
                List<String> itemList = checkRecord.getItemList();
                List<String> deptList = checkRecord.getDeptList();
                List<String> goodsList = checkRecord.getGoodsList();
                List<String> cantaList = checkRecord.getContaList();
                String otherDepts = checkRecord.getOtherDepts();
                String otherItems = checkRecord.getOtherItems();


                if (StringUtils.isNotEmpty(bussId)) {
                    DeclaCheckTracking checkTracking = new DeclaCheckTracking();
                    checkTracking.setId(com.mrd.util.StringUtils.getUUID());
                    checkTracking.setCreateTime(new Date());
                    checkTracking.setCreator(user.getAccount());
                    checkTracking.setDid(bussId);
                    declaCheckTrackingMapper.insertSelective(checkTracking);

                    String containerNoStr = "";
                    if (CollectionUtils.isNotEmpty(cantaList)) {
                        for (String containerNo : cantaList) {
                            containerNoStr += containerNo + ",";
                        }
                        if (StringUtils.isNotEmpty(containerNoStr)) {
                            containerNoStr = containerNoStr.substring(0, containerNoStr.length() - 1);
                        }
                    }

                    DeclaCheckContent checkContent = new DeclaCheckContent();
                    checkContent.setId(com.mrd.util.StringUtils.getUUID());
                    checkContent.setCreator(user.getAccount());
                    checkContent.setCreateTime(new Date());
                    checkContent.setContainerNo(containerNoStr);
                    checkContent.setTrackingId(checkTracking.getId());
                    checkContent.setOtherInspectDept(otherDepts);
                    checkContent.setOtherInspectProject(otherItems);
                    declaCheckContentMapper.insertSelective(checkContent);

                    if (CollectionUtils.isNotEmpty(itemList)) {
                        List<DeclaCheckCtItemRef> checkCtItemRefList = new ArrayList<>();
                        for (String itemId : itemList) {
                            DeclaCheckCtItemRef itemRef = new DeclaCheckCtItemRef();
                            itemRef.setContentId(checkContent.getId());
                            itemRef.setItemId(itemId);
                            itemRef.setCreateTime(new Date());
                            itemRef.setCreator(user.getAccount());
                            declaCheckCtItemRefMapper.insertSelective(itemRef);
                            checkCtItemRefList.add(itemRef);
                        }
                        checkContent.setCheckItemList(checkCtItemRefList);
                    }
                    if (CollectionUtils.isNotEmpty(deptList)) {
                        List<DeclaCheckCtDeptRef> checkCtDeptRefList = new ArrayList<>();
                        for (String deptItemId : deptList) {
                            DeclaCheckCtDeptRef deptRef = new DeclaCheckCtDeptRef();
                            deptRef.setContentId(checkContent.getId());
                            deptRef.setItemId(deptItemId);
                            deptRef.setCreateTime(new Date());
                            deptRef.setCreator(user.getAccount());
                            declaCheckCtDeptRefMapper.insertSelective(deptRef);
                            checkCtDeptRefList.add(deptRef);
                        }
                        checkContent.setCheckDeptList(checkCtDeptRefList);
                    }
                    if (CollectionUtils.isNotEmpty(goodsList)) {
                        List<DeclaCheckGoodsRef> checkGoodsRefList = new ArrayList<>();
                        for (String goodsId : goodsList) {
                            DeclaCheckGoodsRef goodsRef = new DeclaCheckGoodsRef();
                            goodsRef.setContentId(checkContent.getId());
                            goodsRef.setGoodsId(goodsId);
                            goodsRef.setCreateTime(new Date());
                            goodsRef.setCreator(user.getAccount());
                            declaCheckGoodsRefMapper.insertSelective(goodsRef);
                            checkGoodsRefList.add(goodsRef);
                        }
                        checkContent.setCheckGoodsList(checkGoodsRefList);
                    }
                    List<DeclaCheckContent> declaCheckContentList = new ArrayList<>();
                    declaCheckContentList.add(checkContent);
                    checkTracking.setDeclaCheckContentList(declaCheckContentList);
                    return checkTracking;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return null;
    }

    public void sendSMS(DeclaCheckContent declaCheckContent, DeclaCheckResult declaCheckResult) {
        if (declaCheckContent != null || declaCheckResult != null) {
            String trackingId = null;
            List<DeclaCheckCtItemRef> itemRefList = declaCheckContent.getCheckItemList();
            String _itemStr = "";

            if (CollectionUtils.isNotEmpty(itemRefList)) {
                for (DeclaCheckCtItemRef itemRef : itemRefList) {
                    String name = "";
                    Dictionary dictionary = dictionaryService.selectByPrimaryKey(itemRef.getItemId());
                    if (dictionary != null) {
                        name = dictionary.getDictionaryName();
                    }
                    if ("其他".equals(name)) {
                        String otherInspectProject = declaCheckContent.getOtherInspectProject();

                        name += " " + otherInspectProject;
                    }
                    _itemStr += name + ",";
                }
                if (StringUtils.isNotEmpty(_itemStr)) {
                    _itemStr = _itemStr.substring(0, _itemStr.length() - 1);
                }

            }
            List<DeclaCheckCtDeptRef> deptRefList = declaCheckContent.getCheckDeptList();
            String _deptStr = "";
            if (CollectionUtils.isNotEmpty(deptRefList)) {
                for (DeclaCheckCtDeptRef deptRef : deptRefList) {
                    String name = "";
                    Dictionary dictionary = dictionaryService.selectByPrimaryKey(deptRef.getItemId());
                    if (dictionary != null) {
                        name = dictionary.getDictionaryName();
                    }
                    if ("其他".equals(name)) {
                        String otherInspectDept = declaCheckContent.getOtherInspectDept();
                        name += " " + otherInspectDept;
                    }
                    _deptStr += name + ",";
                }
                if (StringUtils.isNotEmpty(_deptStr)) {
                    _deptStr = _deptStr.substring(0, _deptStr.length() - 1);
                }

            }
            DeclaCheckTracking tracking = declaCheckTrackingMapper.selectByPrimaryKey(declaCheckContent.getTrackingId());
            String bizStatus = "";

            if (declaCheckResult != null) {
                String contentId = declaCheckResult.getContentId();
                if (StringUtils.isNotEmpty(contentId)) {
                    declaCheckContent = declaCheckContentMapper.selectByPrimaryKey(contentId);
                }
            }
            if (declaCheckContent != null) {
                trackingId = declaCheckContent.getTrackingId();
            }
            if (StringUtils.isAnyBlank(_deptStr, _itemStr, bizStatus)) {
                List<Map<String, Object>> conts = verifyBiz.verifyContentByTrack(trackingId);
                if (conts != null && conts.size() > 0) {
                    _deptStr = (String) conts.get(0).get("unit");
                    _itemStr = (String) conts.get(0).get("verifyObj");
                    bizStatus = (String) conts.get(0).get("status");
                }
            }
            if (tracking != null && StringUtils.isNotEmpty(tracking.getBizStatus())) {
                bizStatus = tracking.getBizStatus();
                if ("0".equals(bizStatus)) {
                    bizStatus = "查验中";
                } else if ("1".equals(bizStatus)) {
                    bizStatus = "查验完成";
                } else if ("2".equals(bizStatus)) {
                    bizStatus = "查验不通过";
                } else if ("4".equals(bizStatus)) {
                    bizStatus = "海关放行";
                }
            }
            String msg = "报关一线通平台提示：柜号：" + declaCheckContent.getContainerNo() + "，" + _deptStr + "查验，查验项目为：" + _itemStr + "，当前查验状态为：" + bizStatus + "。";

            if (StringUtils.isNotEmpty(trackingId)) {
                DeclaCheckTracking declaCheckTracking = declaCheckTrackingMapper.selectByPrimaryKey(trackingId);

                String declarationId = declaCheckTracking.getDid();
                try {
                    Declaration declaration = declarationBiz.findEntityById(declarationId);
                    String creator = declaration.getCreator();
                    UserService userService = userServiceMapper.selectSMSByUserAccount(creator);
                    if (userService != null && userService.getVerified().equals("1")) {
                        SMSUtil.sendMessage(userId, password, userService.getDeviceCode(), msg);
                    }
                } catch (QueryException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据跟踪id获取报关单相关信息
     */
    public Map<String, Object> declaInfo(String trackId) {
        Map<String, Object> rtn = declaCheckTrackingMapper.selectByTrack(trackId);
        if (rtn != null) {
            List<String> goods = declaCheckTrackingMapper.goodsByTrack(trackId);
            rtn.put("goods", goods);
        }
        return rtn;
    }

    /**
     * 根据查验跟踪id获取查验记录
     */
    public List<Map<String, Object>> verifyContentByTrack(String trackId) {
        List<Map<String, Object>> contents = declaCheckContentMapper.contentByTrack(trackId);
        List<Map<String, Object>> cases = declaCheckContentMapper.caseByTrack(trackId);
        String contentId = null;
        for (Map<String, Object> content : contents) {
            contentId = content.get("id").toString();
            for (Map<String, Object> c : cases) {
                if (contentId.equals(c.get("id").toString())) {
                    if (c.get("dname") != null)
                        content.put("verifyObj", c.get("dname").toString());
                    else
                        content.put("verifyObj", "");
                    break;
                }
            }
        }

        return contents;
    }

    /**
     * 查验结果保存
     */
    @Transactional
    public boolean resultSave(Map<String, Object> map) {
        boolean isSucc = false;
        try {
            //保存查验结果
            DeclaCheckResult dcResult = new DeclaCheckResult();
            String resultId = com.mrd.util.StringUtils.getUUID();
            dcResult.setId(resultId);
            String contentId = map.get("contentId").toString();
            dcResult.setContentId(contentId);
            String verifyStatus = map.get("status").toString();
            dcResult.setBizStatus(verifyStatus);
            dcResult.setCreator(LoginUtil.getLoginAccount());
            dcResult.setCreateTime(new Date());
            dcResult.setDescription(map.get("decirpt").toString());
            if (map.containsKey("otherReasonText")) {
                dcResult.setOtNoPassReason(map.get("otherReasonText").toString());
            }
            declaCheckResultMapper.insertSelective(dcResult);
            if (map.containsKey("reasonId")) {
                List<String> reasons = (List<String>) map.get("reasonId");
                ResultNopassRef rnr = null;
                for (String rid : reasons) {
                    rnr = new ResultNopassRef();
                    rnr.setNotpassId(rid);
                    rnr.setResultId(resultId);
                    rnr.setCreateTime(new Date());
                    resultNopassRefMapper.insertSelective(rnr);
                }
            }
            //修改查验跟踪当前状态
            DeclaCheckContent dcc = declaCheckContentMapper.selectByPrimaryKey(contentId);
            DeclaCheckTracking dct = new DeclaCheckTracking();
            dct.setId(dcc.getTrackingId());
            dct.setBizStatus(verifyStatus);
            declaCheckTrackingMapper.updateByPrimaryKeySelective(dct);
            //报关单状态联动
            String declaState = null;
            if (verifyStatus.equals("0")) {
                declaState = Declaration.DeclarationBusinessState.VERIFY_ING;
            } else if (verifyStatus.equals("1")) {
                declaState = Declaration.DeclarationBusinessState.VERIFY_DOME;
            } else if (verifyStatus.equals("2")) {
                declaState = Declaration.DeclarationBusinessState.VERIFY_FAIL;
            } else if (verifyStatus.equals("4")) {
                //区分放行单位
                String deptId = declaCheckCtDeptRefMapper.selectListByContentId(dcc.getId()).get(0).getItemId();
                Dictionary dt = dictionaryService.selectByPrimaryKey(deptId);
                if ("DEPT_COMMODITY".equals(dt.getDictionaryCode())) {
                    declaState = Declaration.DeclarationBusinessState.VERIFY_SJ_PASS;
                } else if ("DEPT_CUSTOM".equals(dt.getDictionaryCode())) {
                    declaState = Declaration.DeclarationBusinessState.VERIFY_CT_PASS;
                } else {
                    declaState = Declaration.DeclarationBusinessState.VERIFY_OT_PASS;
                }
            }
            //new Integer("a");
            Map dMap = new HashMap();
            dMap.put("trackId", dcc.getTrackingId());
            dMap.put("state", declaState);
            declaCheckContentMapper.changeDeclaStateByTrack(dMap);
            this.sendSMS(dcc, dcResult);
            isSucc = true;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("RuntimeException");
        }
        return isSucc;
    }

    public Page<Map<String, Object>> selectNoPass(Pageable page, Map<String, Object> params) {
        List<Map<String, Object>> pageMapList = resultNopassRefMapper.selectNoPassList(params);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo(pageMapList);
        return new PageImpl<Map<String, Object>>(pageMapList, page, pageInfo.getTotal());
    }
}
